import {
  Component,
  ViewEncapsulation,
  ChangeDetectionStrategy,
  forwardRef,
  ChangeDetectorRef,
  SimpleChanges,
  Input,
  TemplateRef,
  OnChanges,
  OnInit,
} from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { CalendarBaseComponent } from '../core/calendar-base/calendar-base.component';
import { I18NService, DateService, StandardDate, LvConfig, InputBoolean, LvDateRangeTag } from '../core/api';
import { DEFAULT_YEARSOPERATE, LvYearsOperate } from './interface';
import { DatePickerCalendarService } from './date-picker-calendar.service';

@Component({
  selector: 'lv-date-picker-month',
  templateUrl: './date-picker-month.component.html',
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef((): typeof DatePickerMonthComponent => DatePickerMonthComponent),
      multi: true,
    },
  ],
  host: {
    class: 'lv-date-picker-month',
  },
})
export class DatePickerMonthComponent extends CalendarBaseComponent implements OnInit, OnChanges {
  @Input() lvTag: LvDateRangeTag; // for date range picker

  @Input() @InputBoolean() lvPanelTitleReadonly = false;

  @Input() lvCalendarMonthCell: TemplateRef<Date> | null = null;

  @Input() lvCalendarYearOperate: LvYearsOperate = DEFAULT_YEARSOPERATE; // 面板头部年份操作

  activeDateYear;

  language = LvConfig.language;

  private _rootComponent;
  constructor(
    public cdr: ChangeDetectorRef,
    public dateService: DateService,
    public i18n: I18NService,
    private datePickerCalendarService: DatePickerCalendarService,
  ) {
    super(cdr, dateService);
    this.prefixCls = 'lv-date-picker-month';
  }

  trackByIndex(index): any {
    return index;
  }

  renderCalendarMonthUI(): void {
    this.renderCalendarMonthHeader();
    this.renderCalendar({ showMonthPanel: true });
  }

  swithToYearPanel(): void {
    this._rootComponent.showYearByMonth = true;
    this._rootComponent.setPanelState('year');
  }

  renderCalendarMonthHeader(): void {
    this.activeDateYear = this.dateService.format(this.activeDate.localDate, 'yyyy');
  }

  ngOnInit(): void {
    this._rootComponent = this.datePickerCalendarService.getRootComponent();
    this.renderCalendarMonthUI();
  }

  doSelect(value): void {
    this.value = new StandardDate(value);
    this.valueChange.emit(this.value);
    this.renderCalendarMonthUI();
  }

  selectCalendarMonthCell(cell): void {
    if (this.lvPickerMode === 'month' && cell.isDisabled) {
      return;
    }
    this.doSelect(cell.value);
  }

  addYear(num): void {
    if (this.lvCalendarYearOperate.disableChange) {
      return;
    }
    this.activeDate = new StandardDate(this.activeDate.addYears(num));
    this.lvActiveDateChange.emit({ tag: this.lvTag, value: this.activeDate });
    this.renderCalendarMonthUI();
  }

  ngOnChanges(changes: SimpleChanges): void {
    const flag =
      changes.lvActiveDate ||
      this.isDateChange(changes.value) ||
      this.isDateChange(changes.selectedValue) ||
      this.isDateChange(changes.hoverValue);
    if (flag) {
      this.lvActiveDate && (this.activeDate = this.lvActiveDate);
      this.renderCalendarMonthUI();
    }
  }
}
